import React, { Component } from 'react';
import createStore from './store';

const isServer = typeof window === 'undefined';
const __NEXT_REDUX_STORE = '__NEXT_REDUX_STORE';

const getOrCreateStore = (initialState) => {
    if (isServer) {
        return createStore(initialState);
    }
    // 客户端切换都会触发，保证客户端只有一个store，需要判断处理
    if (!window[__NEXT_REDUX_STORE]) {
        window[__NEXT_REDUX_STORE] = createStore(initialState);
    }
    return window[__NEXT_REDUX_STORE];
};

const appHoc = (Comp) => {
    class WithReduxApp extends Component {
        constructor(props) {
            super(props);
            this.store = getOrCreateStore(props.initialReduxState);
        }
        render() {
            const { Component, pageProps, ...rest } = this.props;
            // 服务端和客户端都会执行constructor, 生成store传到子组件中
            return <Comp Component={Component} pageProps={pageProps} store={this.store} {...rest} />;
        }
    }

    // 包裹_app的hoc，app的getInitialProps会在服务端渲染一次，页面切换每次触发
    WithReduxApp.getInitialProps = async (appCtx) => {
        let reduxStore = getOrCreateStore();
        appCtx.ctx.isServer = isServer;
        if (isServer) {
            const { req } = appCtx.ctx;
            const session = req.session || {};
            if (session.userInfo) {
                reduxStore = getOrCreateStore({ user: session.userInfo });
            } else {
                reduxStore = getOrCreateStore();
            }
        } else {
            reduxStore = getOrCreateStore();
        }

        let appProps = {};
        if (typeof Comp.getInitialProps === 'function') {
            appCtx.ctx.store = reduxStore;
            appProps = await Comp.getInitialProps(appCtx);
        }
        // 返回的数据服务器上，会被序列化到html中
        return {
            ...appProps,
            initialReduxState: reduxStore.getState()
        };
    };
    return WithReduxApp;
};

export default appHoc;